package testJdk.base.juc_test.test_volatile;

import lombok.SneakyThrows;
import org.junit.Test;

/**
 * @ClassName : learn_jdk.base.juc_test.test_volatile.TestVolatile
 * @Description : 演示内存可见性、volatile用法
 * Created by cyd on 2021-10-22 09:23:04
 */
public class TestVolatile {

    @Test
    public void test01() {
        ThreadDemo threadDemo = new ThreadDemo();
        new Thread(threadDemo).start();
        System.out.println("main线程中，一开始flag=" + threadDemo.isFlag());
        while (true) {
            if (threadDemo.isFlag()) {
                System.out.println("flag的值已经改变为：" + threadDemo.isFlag() + "循环结束");
                break;
            }
        }
    }

    @Test
    public void test02() {
        ThreadDemo threadDemo = new ThreadDemo();
        new Thread(threadDemo).start();
        System.out.println("main线程中，一开始flag=" + threadDemo.isFlag());
        while (true) {
            synchronized (threadDemo) {
                if (threadDemo.isFlag()) {
                    System.out.println("flag的值已经改变为：" + threadDemo.isFlag());
                    break;
                }
            }
        }
    }

    @Test
    public void test03() {
        VolatileThreadDemo volatileThreadDemo = new VolatileThreadDemo();
        new Thread(volatileThreadDemo).start();
        System.out.println("main线程中，一开始flag=" + volatileThreadDemo.isFlag());
        while (true) {
            if (volatileThreadDemo.isFlag()) {
                System.out.println("flag的值已经改变为：" + volatileThreadDemo.isFlag());
                break;
            }
        }
    }
}

class ThreadDemo implements Runnable {

    private boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    @SneakyThrows
    @Override
    public void run() {

        Thread.sleep(2000);
        flag = true;
        System.out.println("子线程中flag=" + isFlag());
    }
}

class VolatileThreadDemo implements Runnable {

    private volatile boolean flag = false;

    public boolean isFlag() {
        return flag;
    }

    @SneakyThrows
    @Override
    public void run() {

        Thread.sleep(2000);
        flag = true;
        System.out.println("子线程中flag=" + isFlag());
    }
}